/**
 *    title:  mysql.cpp
 *    author:  sleeeeeping
 *    created:  2024-09-12 19:30:52
**/
#include "mysql.hpp"

MySQL::MySQL() {
    mysql = mysql_init(nullptr);
    if (mysql == nullptr) {
        showError();
    }
}


MySQL::~MySQL() {
    mysql_close(mysql);
}

bool MySQL::connect(const std::string &host, 
    const std::string &user, const std::string &passwd, 
    const std::string &db, u32 port) {
        mysql = mysql_real_connect(mysql,
            host.c_str(),
            user.c_str(), passwd.c_str(),
            db.c_str(), port,
            nullptr, 0);
        if (mysql == nullptr) {
            showError();
            return false;
        }
        return true;
    }

int MySQL::query(const std::string &sql) {
    if (mysql_real_query(mysql, sql.c_str(), size(sql))) {
		showError();
		return -1;
	}
	if (mysql_field_count(mysql) == 0) {
		return mysql_affected_rows(mysql);
	}
	MYSQL_RES *res = mysql_store_result(mysql);
	size_t num_rows = mysql_num_rows(res);
	result.clear();

	for (size_t i = 0; i < num_rows; ++i) {
		std::vector<std::string> arr;
		size_t num_fields = mysql_num_fields(res);
		MYSQL_ROW row = mysql_fetch_row(res);
		for(size_t j = 0; j < num_fields; ++j) {
			if (row[j]) {
				arr.push_back(row[j]);
            }
        }
		result.push_back(arr);
	}
	return num_rows;
}

const std::vector<std::vector<std::string>> &MySQL::getQueryRestult(void) {
    return result;
}

bool MySQL::getAutoCommit(void) {
    if (query("show variables like \'autocommit\';") < 1) {
        return false;
    }
	return result[0][1] == "NO";
}

bool MySQL::setAutoCommit(bool isAutoCommit) {
	return !mysql_autocommit(mysql, isAutoCommit);
}

bool MySQL::commit(void) {
    return !mysql_commit(mysql);
}

bool MySQL::rollback(void) {
	return !mysql_rollback(mysql);
}

bool MySQL::setCharacterSet(const std::string &csname) {
	return !mysql_set_character_set(mysql, csname.c_str());
}

const char* MySQL::getCharacterSet(void) {
	return mysql_character_set_name(mysql);
}

void MySQL::showError(void) {
    std::cout << "ERROR " << mysql_errno(mysql) << ": " 
        << mysql_error(mysql) << '\n';
}